<?php

// @formatter:off
/**
 * @file WCActiveTagsHolder.php
 * @author Alejandro Dario Simi
 * @date $Date: 2014-05-04 01:33:52 +0000 (Sun, 04 May 2014) $
 *
 * $Id: WCActiveTagsHolder.php 111 2014-05-04 01:33:52Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/trunk/includes/holders/WCActiveTagsHolder.php $
 */
// @formatter:on

/**
 * @class WCActiveTagsHolder
 */
class WCActiveTagsHolder extends WCSingleton {
	/**
	 * @var WCTag[int][string] This variable holds a list of active tags
	 * separated by group and associated with their names.
	 */
	protected $_tags = array();
	/**
	 * @var string[] List of tag names of real active tags.
	 */
	protected $_tagsNoSpecials = array();
	/**
	 * Class constructor.
	 */
	public function __construct() {
		$this->load();
	}
	//
	// Public methods.
	/**
	 * This method enforces the existence of active tags on every group.
	 */
	public function createSpecialTags() {
		//
		// Loading global pointers.
		global $wcActiveTagHooks;
		//
		// Walking over every group.
		foreach(WCGroupsHolder::I()->items() as $group) {
			//
			// Walking over every special tag.
			foreach($this->_tags as $name => $list) {
				if(!isset($wcActiveTagHooks[$name]["groups"]) || in_array($group->id, $wcActiveTagHooks[$name]["groups"])) {
					//
					// Checking if the tag is present.
					if(count(WCTagsHolder::I()->itemByNameInGroup($name, $group)) == 0) {
						//
						// Creating the tag because it's
						// not present.
						$tag = WCTagsHolder::I()->createInGroup($name, $group);
					}
				}
			}
		}
	}
	public function get($name, WCGroup &$group) {
		//
		// Setting a default value to be returned.
		$out = false;
		//
		// Creating shortcut for group's id.
		$gid = $group->id;
		//
		// Checking list existence.
		if(isset($this->_tags[$name][$gid])) {
			//
			// Checking if the active tag is loaded
			if($this->_tags[$name][$gid] === false) {
				//
				// Loading active tag.
				$this->_tags[$name][$gid] = new WCActiveTag();
				$this->_tags[$name][$gid]->load($name, $group);
			}
			//
			// Checking active tag status.
			if($this->_tags[$name][$gid]->ok()) {
				//
				// Active tag is okey, setting it to be returned.
				$out = $this->_tags[$name][$gid];
			}
		}
		//
		// Returning result.
		return $out;
	}
	/**
	 * @param string $name
	 * @param WCGroup $group
	 * @return WCActiveTagHook
	 */
	public function hook($name, WCGroup &$group) {
		//
		// Setting a default value to be returned.
		$out = false;
		//
		// Obtaining active tag.
		if($at = $this->get($name, $group)) {
			//
			// Setting hook to be returned.
			$out = $at->hook();
		}
		//
		// Returning result.
		return $out;
	}
	public function isActive($name, $onlyActives = false) {
		return $onlyActives ? in_array($name, $this->_tagsNoSpecials) : isset($this->_tags[$name]);
	}
	public function names($onlyActives = false) {
		return $onlyActives ? $this->_tagsNoSpecials : array_keys($this->_tags);
	}
	public function reload() {
		$this->_tags = array();
		$this->load();
	}
	public function tags(WCGroup &$group, $onlyActives = false) {
		$out = array();
		//
		// Creating a list of tags base on a group.
		foreach($this->_tags as $name => $value) {
			//
			// Filtering special tags if it's required.
			if(!$onlyActives || in_array($name, $this->_tagsNoSpecials)) {
				$out[$name] = $this->get($name, $group);
			}
		}
		//
		// Cleaning empty results.
		foreach($out as $key => $value) {
			if($value === false) {
				unset($out[$key]);
			}
		}
		//
		// Returning active tags.
		return $out;
	}
	//
	// Protected methods.
	protected function load() {
		//
		// Loading global pointers;
		global $wcActiveTagHooks;
		global $wcSpecialTags;
		//
		// Generating a structure to hold and manage active tags.
		// @{
		//
		// Adding special tags as active tags.
		foreach($wcSpecialTags as $name) {
			$this->_tags[$name] = array();
		}
		//
		// Adding active tag's hooks. This supersedes special tags
		// on duplicates.
		foreach($wcActiveTagHooks as $name => $hook) {
			$this->_tags[$name] = array();
			$this->_tagsNoSpecials[] = $name;
		}
		//
		// Adding empty entries for each group on every active tag.
		foreach($this->_tags as $name => $list) {
			//
			// Walking over each group.
			foreach(WCGroupsHolder::I()->itemIds() as $gid) {
				if(!isset($wcActiveTagHooks[$name]["groups"]) || in_array($gid, $wcActiveTagHooks[$name]["groups"])) {
					//
					// Creating an entry for this group.
					$this->_tags[$name][$gid] = false;
				}
			}
		}
		//@}
	}
}
